package com.zx.scp.service.impl;

import com.zx.map.service.BaseAcctInfoService;
import com.zx.map.service.CustAcctLogService;
import com.zx.map.service.HistoryPayCardInfoService;
import com.zx.map.service.OrdLogService;
import com.zx.map.service.domain.nocard.NocardPayReturnDomain;
import com.zx.map.service.model.BaseAcctInfoModel;
import com.zx.map.service.model.CustAcctLogModel;
import com.zx.map.service.model.HistoryPayCardInfoModel;
import com.zx.map.service.model.OrdLogModel;
import com.zx.map.utils.CommonResponseUtils;
import com.zx.map.utils.SUConstants;
import com.zx.mobile.PayRateHelper;
import com.zx.platform.utils.DateUtils;
import com.zx.scp.service.NoCardIncomeService;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;

import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;

/**
 * Created by IntelliJ IDEA. User: Administrator Date: 15-6-7 Time: 上午1:12 To
 * change this template use File | Settings | File Templates.
 */
@Component("noCardIncomeService")
public class NoCardIncomeServiceImpl implements NoCardIncomeService {
    /**
     * log
     */
    private static Logger log = Logger.getLogger(NoCardIncomeServiceImpl.class);
    @Autowired
    private TransactionTemplate transactionTemplate;
    @Autowired
    private OrdLogService ordLogService;
    @Autowired
    private BaseAcctInfoService baseAcctInfoService;
    @Autowired
    private HistoryPayCardInfoService historyPayCardInfoService;
    @Autowired
    private CustAcctLogService custAcctLogService;

    @Override
    public Map notifyOrder(final NocardPayReturnDomain noCardCallBack) throws Exception {
        return transactionTemplate.execute(new TransactionCallback<Map>() {
            @Override
            public Map doInTransaction(TransactionStatus arg0) {
                // 获取订单信息 如果该订单已经为终态 不做任何处理 否则进行更新操作
                OrdLogModel tempOrd = ordLogService.selectByPrimaryKeyAndLineLock(noCardCallBack.getOrderId());
                if (null != tempOrd) {
                    if (!("S".equals(tempOrd.getTransStatus()) || "F".equals(tempOrd.getTransStatus()))) {
                        String amount = noCardCallBack.getAmount();
                        // 根据酷贝支付信息 更新订单支付相关信息
                        tempOrd.setPaymentId(noCardCallBack.getYbOrderId());
                        tempOrd.setPaymentAmt(Double.valueOf(amount));
                        // 补充支付时间
                        tempOrd.setPaymentTime(DateUtils.dateToString(new Date(),
                                "yyyyMMddHHmmss"));
                        tempOrd.setTransStatus(noCardCallBack.getStatus());// 状态int 0：失败 1：成功
                        tempOrd.setUpdateDate(new Date());
                        tempOrd.setDebitFlag(noCardCallBack.getCardType());
                        tempOrd.setBankCode(transformBankCode(noCardCallBack.getBankCode())); //易宝bankcode 转换
                        BigDecimal feeAmt = new BigDecimal(amount).multiply(
                                new BigDecimal(PayRateHelper.NOCARDINCOMERATE))
                                .setScale(2, BigDecimal.ROUND_UP);
                        tempOrd.setFeeAmt(feeAmt.doubleValue());
                        ordLogService.update(tempOrd);
                        if ("S".equals(noCardCallBack.getStatus())) {
                            // 如果交易成功 记录账户余额 余额=交易金额*(1-扣率)
                            // 计算结算金额 支付金额 - 商户手续费
                            BigDecimal settleAmt = new BigDecimal(amount).subtract(feeAmt)
                                    .setScale(2, BigDecimal.ROUND_DOWN);
                            try {//目的 不因账务处理失败 而订单更新回滚
                                //对账户信息增加行锁
                                BaseAcctInfoModel acct = baseAcctInfoService.getModelByKeyAndLineLock(tempOrd.getMerchantId());
                                baseAcctInfoService.addBaseAcctBalByKeyModel(settleAmt, acct);
                                // 增加账户明细记录
                                CustAcctLogModel custModel = transformCustAcct(
                                        acct, tempOrd, settleAmt);
                                custAcctLogService.add(custModel);
                                // 记录历史收款账户  满足后4位相同的情况下 才进行保存
                                if(StringUtils.isNotBlank(tempOrd.getBankAccount()) && tempOrd.getBankAccount().endsWith(noCardCallBack.getLastNo())) {
                                    HistoryPayCardInfoModel payCardModel = transformPayCardModel(tempOrd);
                                    historyPayCardInfoService.addOrUpdate(payCardModel);
                                }
                            } catch (Exception e) {
                                log.error("系统内部异常 ", e);
                            }
                        }
                        return CommonResponseUtils.successResponse("处理成功");
                    } else {
                        log.info("无卡收款订单已是终态不做处理");
                        return CommonResponseUtils.successResponse("订单已是终态");
                    }
                } else {
                    log.error("异常订单,未发现订单，订单信息如下："
                            + ToStringBuilder.reflectionToString(noCardCallBack));
                    return CommonResponseUtils.failureResponse("未发现订单");
                }
            }
        });
    }

    @Override
    public Map checkPayStatus(NocardPayReturnDomain nocardPayReturnDomain) {
        return null;
    }


    /**
     * 模型转换
     *
     * @param tempOrd
     * @return
     */
    private HistoryPayCardInfoModel transformPayCardModel(OrdLogModel tempOrd) {
        HistoryPayCardInfoModel payCardModel = new HistoryPayCardInfoModel();
        payCardModel.setBankAccount(tempOrd.getBankAccount());
        payCardModel.setBankCode(tempOrd.getBankCode());
        payCardModel.setBankName("");//没有用户名
        payCardModel.setCreateDate(new Date());
        payCardModel.setDebitFlag(tempOrd.getDebitFlag());
        payCardModel.setIdentityNo(tempOrd.getIdentityNo());
        payCardModel.setMerchantId(tempOrd.getMerchantId());
        payCardModel.setMerSysAccount(tempOrd.getMerSysAccount());
        return payCardModel;
    }

    public static CustAcctLogModel transformCustAcct(
            BaseAcctInfoModel baseModel, OrdLogModel tempOrd, BigDecimal settleAmt) {
        CustAcctLogModel temp = new CustAcctLogModel();
        temp.setAcctBal(baseModel.getAvlBal());
        temp.setAcctType("B");
        temp.setCreateDate(new Date());
        temp.setCustId(tempOrd.getMerchantId());
        temp.setCustSysaccount(tempOrd.getMerSysAccount());
        temp.setOrdId(tempOrd.getOrdId());
        temp.setRemark("");
        temp.setOriginalAmt(tempOrd.getPaymentAmt());//增加账户变化原始交易金额
        temp.setTransAmt(settleAmt.doubleValue());
        temp.setTransType(SUConstants.TRANSTYPE_NOCARDINCOME);
        return temp;
    }

    /**
         * 接口编码转系统银行编码 102 中国工商银行 103 中国农业银行 104 中国银行 105 中国建设银行 301 交通银行 302 中信银行
         * 303 中国光大银行 305 中国民生银行 306 广东发展银行 307 深圳发展银行 308 招商银行 309 兴业银行 310
         * 上海浦东发展银行 403 中国邮政储蓄银行
         *
         * @param bankcode
         * @return
         */
    public  String transformBankCode(String bankcode) {
            String bankCode = null;
            if ("ICBC".equals(bankcode)) {
                bankCode = "102";
            } else if ("ABC".equals(bankcode)) {
                bankCode = "103";
            } else if ("BOC".equals(bankcode)) {
                bankCode = "104";
            } else if ("CCB".equals(bankcode)) {
                bankCode = "105";
            } else if ("".equals(bankcode)) {//交通银行不支持
                bankCode = "301";
            } else if ("ECITIC".equals(bankcode)) {
                bankCode = "302";
            } else if ("CEB".equals(bankcode)) {
                bankCode = "303";
            } else if ("CMBC".equals(bankcode)) {
                bankCode = "305";
            } else if ("GDB".equals(bankcode)) {//modify 20151008 广东发展银行
                bankCode = "306";
            } else if ("".equals(bankcode)) {//深圳发展银行不支持
                bankCode = "307";
            } else if ("CMBCHINA".equals(bankcode)) {
                bankCode = "308";
            } else if ("CIB".equals(bankcode)) {
                bankCode = "309";
            } else if ("SPDB".equals(bankcode)) {
                bankCode = "310";
            } else if ("POST".equals(bankcode)) {
                bankCode = "403";
            } else if ("PINGAN".equals(bankcode)) {
                bankCode = "404";
            } else if ("BCCB".equals(bankcode)) {
                bankCode = "405";
            } else if ("SHB".equals(bankcode)) {
                bankCode = "406";
            } else if ("HXB".equals(bankcode)) {
                bankCode = "407";
            }
            return bankCode;
        }
}
